import { LevelDt } from '../../../Framework/Common/CommonInterface';
import { propDtMgr } from '../../../Framework/Data/DataBaseMgr';
import DataMgr from '../../../Framework/Data/DataMgr';
import ResMgr from '../../../Framework/Res/ResMgr';
import ModuleBase from './ModuleBase';
import ModuleMgr from './ModuleMgr';
import PropLayer from './PropLayer';
const { ccclass, property } = cc._decorator;
@ccclass
export default class TiledMapCtrl extends ModuleBase {
    private _tiledMap: cc.TiledMap = null;
    get tiledMap() {
        if (!this._tiledMap) {
            this._tiledMap = this.getComponent(cc.TiledMap);
        }
        return this._tiledMap;
    }
    private _tiledSize: cc.Size = null;
    private _mapSize: cc.Size = null
    private _propLayer: PropLayer = null;
    onInit(...rest: any[]): void {
        //设置地图
        //先获取地图资源
        let levelDt = DataMgr.instance.getMgr("levelDtMgr").getDataByCurIndex() as LevelDt;
        let resName = levelDt.mapName;
        let tmxasset = ResMgr.instance.getRes<cc.TiledMapAsset>("TiledMap", resName);
        this.tiledMap.tmxAsset = tmxasset;
        //每个格子的大小，是像素值
        this._tiledSize = this.tiledMap.getTileSize();
        //地图上格子的块数
        this._mapSize = this.tiledMap.getMapSize();
        this._propLayer = ModuleMgr.instance.getModule<PropLayer>("PropLayer");
        for (let i = 0; i < this.tiledMap.getLayers().length - 1; i++) {
            //let blockNode = this.node.getChildByName("obstacle" + (i + 1));
            //设置地图上的每一层的层级索引
            //blockNode.setSiblingIndex(i + 2);
            //console.log(blockNode.zIndex);
            let blockNode = this.tiledMap.getLayer("obstacle" + (i + 1)).node;
            blockNode.zIndex = i + 1;
            console.log(blockNode.getSiblingIndex());

        }
    }

    //将像素值转成格子坐标
    getTiledPosByPoxiPos(poxiPos: cc.Vec2) {
        //将像素转成格子坐标
        //像素的x值/一个格子的大小，向下取整，可以得到x坐标
        let x = Math.floor(poxiPos.x / this._tiledSize.width);
        //地图大小的height-(Math.floor(像素的y值/一个格子的大小)+1);
        let y = this._mapSize.height - Math.floor(poxiPos.y / this._tiledSize.height) - 1;
        //let y = Math.floor(poxiPos.y / this._tiledSize.height);
        return cc.v2(x, y);
    }
    //将坐标转成像素值
    getPoxiByTiledPos(tiledPos: cc.Vec2) {
        let x = tiledPos.x * this._tiledSize.width + this._tiledSize.width / 2;
        let y = (this._mapSize.height - tiledPos.y - 1) * this._tiledSize.height + this._tiledSize.height / 2;
        //let y = tiledPos.y * this._tiledSize.height + this._tiledSize.height / 2;
        return cc.v2(x, y);
    }

    getCentralPos(poxiPos: cc.Vec2) {
        let tilePos = this.getTiledPosByPoxiPos(poxiPos);
        let centerPos = this.getPoxiByTiledPos(tilePos);
        return centerPos;
    }
    getAllBirthPos() {
        //存储的是初始化每个格子的中心的像素值
        let arrPos: cc.Vec2[] = [];
        //先获取对象组
        let objGroup: cc.TiledObjectGroup = this.tiledMap.getObjectGroup("initPos");
        //获取这个对象组中的所有对象
        let arrObj = objGroup.getObjects();
        for (let obj of arrObj) {
            let x = obj["x"];
            let y = obj["y"];
            //这个是像素值需要将像素值转换成格子坐标
            let centerPos = this.getCentralPos(cc.v2(x, y));
            arrPos.push(centerPos);
        }
        return arrPos;
    }
    //判断是否出界
    isOutOfMap(tilePos: cc.Vec2) {
        if (tilePos.x < 0 || tilePos.x > this._mapSize.width - 1
            || tilePos.y < 0 || tilePos.y > this._mapSize.height - 1) {
            return true;
        }
        return false;
    }

    //通过坐标获取属性
    getPropertyByColliTiled(tiledPos: cc.Vec2) {
        let layerIndex = tiledPos.y + 1;
        //通过索引获取层
        // let arrLayers: cc.TiledLayer[] = this._tiledMap.getLayers()
        // let layer = arrLayers[(layerIndex + 1)];
        //通过层的名字获取层
        let layer = this.tiledMap.getLayer("obstacle" + layerIndex);
        let gid = layer.getTileGIDAt(tiledPos);
        if (gid == 0) {
            return null;
        }
        let property = this._tiledMap.getPropertiesForGID(gid);
        return property;
    }


    //移动箱子
    /**
     * 
     * @param tiledPos 碰撞点所在的格子坐标
     * @param dir 推动的方向
     * @param layerIndex 箱子所在的层
     */
    moveBox(tiledPos: cc.Vec2, dir: cc.Vec2, layerIndex: number) {
        //通过名字获取层
        let curLayer = this.tiledMap.getLayer("obstacle" + layerIndex);
        //获取箱子需要推动到的格子坐标
        let nextTiledPos = tiledPos.clone().add(cc.v2(dir.x, -dir.y));
        //通过名字获取下一层
        let nextLayerIndex = layerIndex - dir.y;
        if (nextLayerIndex == nextTiledPos.y + 1) {
            //更新道具的位置
            this._propLayer.refreshProp(tiledPos, nextTiledPos);
        }
        let nextLayer = this.tiledMap.getLayer("obstacle" + nextLayerIndex);
        //获取当前箱子格子的gid的值
        let gid = curLayer.getTileGIDAt(tiledPos);
        //获取TiledTile组件
        let tiledTile = curLayer.getTiledTileAt(tiledPos.x, tiledPos.y, true);
        cc.tween(tiledTile.node)
            .by(0.3, { position: cc.v3(this._tiledSize.width * dir.x, this._tiledSize.height * dir.y) })
            .call(() => {
                //设置gid的值
                //当前箱子的所在格子的gid
                curLayer.setTileGIDAt(0, tiledPos.x, tiledPos.y);
                //设置格子的上半部分，如果出界，就直接设置为0
                if (!this.isOutOfMap(nextTiledPos)) {
                    nextLayer.setTileGIDAt(gid, nextTiledPos.x, nextTiledPos.y);
                }
            })
            .removeSelf()
            .start()
    }

    //移除障碍物
    removeObstacle(tiledPos: cc.Vec2) {
        let layerIndex = tiledPos.y + 1;
        let layer = this.tiledMap.getLayer("obstacle" + layerIndex);
        //修改这个位置的gid
        layer.setTileGIDAt(0, tiledPos.x, tiledPos.y);
        //如果是箱子的话，上部分若是出界，就不需要设置gid,如果为出界就需要销毁
        let upTiled = cc.v2(tiledPos.x, tiledPos.y - 1);
        if (this.isOutOfMap(upTiled)) {
            return;
        }
        layer.setTileGIDAt(0, upTiled.x, upTiled.y);
    }
    //获取所有可炸障碍物(非草丛)的格子坐标，用于放置道具
    getAllTiledPosSetProp() {
        //遍历地图上的格子
        let arrTile: cc.Vec2[] = []
        for (let i = 0; i < this._mapSize.width; i++) {
            for (let j = 0; j < this._mapSize.height; j++) {
                let tile = cc.v2(i, j);
                let property = this.getPropertyByColliTiled(tile);
                if (property) {
                    if (property.blast && !property.visible) {
                        arrTile.push(tile);
                    }
                }
            }
        }
        return arrTile;
    }
}